﻿@*
// Copyright (c) 2010-2013 SharpDX - Alexandre Mutel
// 
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// 
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
// 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.       
*@
@model SharpDoc.TemplateContext
@using System.IO.Compression
@using System.Text
@using System.Text.RegularExpressions
@using SharpDoc.Model
@using System.IO;
@using SharpDoc;
@functions {
    private const string JoomlaContentUrl = "index.php?option=com_sharpdoc&amp;Itemid={0}&amp;id={1}";

	public static string SqlEscapeString(string text)
    {
		if (text == null)
            return null;
        text = text.Replace("\\", "\\\\");
        text = text.Replace("'", "\\'");
        return text;
    }

	public static string GetPageId(string pageId)
    {
		// Use lower case for pages
        pageId = pageId.Replace("_", "-");
        pageId = pageId.ToLowerInvariant();
        return pageId;
    }

	public NTopic GetParentTopicUrl(IModelReference member)
    {
		// Use topic PageId as url
        var topic = member as NTopic;
		if (topic != null)
        {
            while (topic != null && !topic.IsPageIdOnUrl)
            {
                topic = topic.Parent;
            }
        }
		else
        {
            topic = Model.ClassLibraryTopic;
        }
        return topic;
    }

	public string GetShortUrl(IModelReference member, int index)
    {
		// For Index == 0, URL is documentation
        var urlShort = "documentation";

		if (index > 0)
        {
	        var topic = GetParentTopicUrl(member);

			// Don't append twice topic PageId
			if (topic != null && !ReferenceEquals(topic, member))
            {
                urlShort += "/" + topic.PageId;
            }

            var pageId = GetPageId(member.PageId);
            urlShort += "/" + GetPageId(pageId);
        }
        return urlShort;
    }

    public void WriteToSql(IModelReference member, string content)
    {
        var writer = (StreamWriter)Model.Param.SqlWriter;

		if (member == null)
        {
			if (content == null)
            {
                Sqlsdx_sh404sef_urls.AppendLine(";");
                Sqlsdx_doc.AppendLine(";");
                Sqlsdx_sh404sef_urls.AppendLine("ALTER TABLE `sdx_sh404sef_urls` CHANGE COLUMN `id` `id` INT(11) NOT NULL AUTO_INCREMENT FIRST;");

                writer.Write(Sqlsdx_sh404sef_urls);
                writer.Write(Sqlsdx_doc);
				writer.Flush();
            }
		   return;
        }

		// Use lower case for pages
        var pageId = GetPageId(member.PageId);
        var memberIndex = member.Index;

		// Calculate Short url
		var urlShort = GetShortUrl(member, member.Index);

		// Calculate Long url
        var topic = GetParentTopicUrl(member);
        var itemId = "109";
		if (topic != null && memberIndex > 0)
        {
            var topicParamItemId = topic.Parameters.FirstOrDefault(topicParam => topicParam.Name == "ItemId");
			if (topicParamItemId != null)
            {
                itemId = topicParamItemId.value;
            }
        }
        var urlLong = string.Format(JoomlaContentUrl, itemId, memberIndex);

        var contentBuffer = Encoding.ASCII.GetBytes(content);
        var memoryStream = new MemoryStream();
		using (var gz = new DeflateStream(memoryStream, CompressionMode.Compress, false))
        {
			gz.Write(contentBuffer, 0, contentBuffer.Length);
		}
        var contentGZipBase64 = Convert.ToBase64String(memoryStream.ToArray());
	

		if (CountInserts == 0)
        {
            Sqlsdx_sh404sef_urls.Append(@"INSERT INTO `sdx_sh404sef_urls` (`id`, `cpt`, `rank`, `oldurl`, `newurl`, `dateadd`) VALUES ");
            Sqlsdx_doc.Append(@"INSERT INTO `sdx_doc` (`id`,`title`,`alias`,`maintext`) VALUES ");
        }
		else
        {
            Sqlsdx_sh404sef_urls.Append(",");
            Sqlsdx_doc.Append(",");
        }

        Sqlsdx_sh404sef_urls.AppendLine(@" (" + memberIndex + @", 0, 0, '" + urlShort + @"', '" + urlLong + @"', '0000-00-00')");
		Sqlsdx_doc.AppendLine(@" (" + memberIndex + @",'" + SqlEscapeString(member.PageTitle) + @"','" + pageId + @"','" + contentGZipBase64 + @"') ");

        CountInserts++;
		if (CountInserts == 50)
        {
            Sqlsdx_sh404sef_urls.AppendLine(";");
            Sqlsdx_doc.AppendLine(";");
            CountInserts = 0;
        }
    }

    public Func<LinkDescriptor, string> PreviousLinkResolver { get; set; }

    public int CountInserts { get; set; }

    public StringBuilder Sqlsdx_sh404sef_urls { get; set; }

    public StringBuilder Sqlsdx_doc { get; set; }

    public string LinkToSqlDb(LinkDescriptor link)
    {
        string url = null;
		
        switch (link.Type) {
            case LinkType.Local:			
                url = GetShortUrl(link.LocalReference, link.Index);
                break;
            default:
                return PreviousLinkResolver(link);
        }
        return string.Format("<a href=\"{0}\" {1}>{2}</a>", url, link.Attributes ?? "", Escape(link.Name));
    }
}

@{
	// Replace default link resolver and use a special one for local links
    PreviousLinkResolver = Model.LinkResolver;
    Model.LinkResolver = LinkToSqlDb;

    const string fileName = "sharpdx-joomla.sql";
	if (File.Exists(fileName))
    {
        File.Delete(fileName);
    }
    var writer = new StreamWriter(new FileStream(fileName, FileMode.CreateNew, FileAccess.Write), Encoding.ASCII);
    Model.Param.SqlWriter = writer;

	writer.WriteLine(@"
SET SESSION sql_mode='NO_AUTO_VALUE_ON_ZERO';
ALTER TABLE `sdx_sh404sef_urls` CHANGE COLUMN `id` `id` INT(11) NOT NULL FIRST;
TRUNCATE TABLE `sdx_sh404sef_urls`;	
TRUNCATE TABLE `sdx_doc`;	
");

	Sqlsdx_sh404sef_urls = new StringBuilder();

	Sqlsdx_doc = new StringBuilder();

    Model.WriteTo = WriteToSql;
}